package date;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期工具类 SimpleDateFormat TimeZone Locale
 * Java运行.class文件 Could not find or load main class https://blog.51cto.com/u_16213344/7371450
 * 将文件直接编译为class，然后运行
 * 编译：javac -encoding UTF-8 DateUtil1.java
 *  可以将package注释，java -cp . date.DateUtil1，不需要加.class后缀
 *  如果带包名，复制时需要连目录结构一起复制 date/DateUtil1.class
 *  在date同级目录执行：java -cp . date.DateUtil1，-classpath或-cp选项指定类路径
 */
public class DateUtil1 {


    /**
     * Java —— 时区（夏令时）问题 https://www.cnblogs.com/memory4young/p/java-timezone.html
     * 解决方法：
     * 如果涉及的地方比较多，改动起来就比较麻烦
     * 还有个更简单的：在JVM启动的时候，加入参数 -Duser.timezone=GMT+08
     */
    public static void main(String[] args) throws Exception {

        SimpleDateFormat simpleDateFormat0 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("dd-MMMM-yyyy EEEE MMM M月 E", Locale.SIMPLIFIED_CHINESE);
        SimpleDateFormat simpleDateFormat3 = new SimpleDateFormat("dd-MMMM-yyyy EEEE MMM M月 E", Locale.US);

        String[] monthsUs = simpleDateFormat3.getDateFormatSymbols().getMonths();

        // linux系统 默认是en_US  en_US.UTF-8  windows系统默认是zh_CN.utf8
        System.out.println(Locale.getDefault(Locale.Category.FORMAT));

        // 夏令时（Daylight Saving Time，简称DST）问题 https://blog.csdn.net/m0_37539286/article/details/130445667
        // 夏令时是一种将时间调快一小时的做法，通常在夏季实施
        Date date0 = simpleDateFormat0.parse("1988-04-15");
        Date date00 = simpleDateFormat0.parse("1989-06-18");

        TimeZone tz = TimeZone.getTimeZone("Europe/Berlin"); // 柏林时区 UTC +1:00
        // jvm默认时区 -Duser.timezone=Asia/Shanghai
        TimeZone tz1 = TimeZone.getDefault(); // 获取系统默认时区 GMT+08:00
        System.out.println(tz1); // sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null]
        
        boolean b = tz.inDaylightTime(date0); // 判断当前日期是否处于夏令时
        boolean b1 = tz1.inDaylightTime(date0);
        boolean bb = tz.inDaylightTime(date00);
        boolean bb1 = tz1.inDaylightTime(date00);

        /**
         * JVM默认时区为:Asia/Shanghai与java程序中GMT+08不一致异常
         * https://www.jb51.net/article/266311.htm
         * 在Spring程序中配置了spring.jackson.time-zone=GMT+08时
         * 经过排查，发现是JVM的默认时区为
         * Asia/Shanghai，两者不一致，然后Asia/Shanghai 这个时区并不一定与GMT+08这个时区相等，他们是2种定义标准。
         * Asia/Shanghai 这个代表的是中国的时区，但在历史中，有国家（包含中国）政策颁布了在1986-1991年等还存在夏令时。
         * 在这样的时间区间，夏季时，会将时间拨快1个小时（即东9区时间），夏季结束时会再次将时间拨回一个小时（即东8区时间）。
         * 所以要保证程序显示的时间没有问题，需要将JVM和spring.jackson.time-zone设置的时区保持一致即可解决问题。
         * 关于时区的冷知识 https://zhuanlan.zhihu.com/p/35237352?utm_id=0
         * 理论上说timezone db只确保1970年之后的准确性（实践上其实还是会有bug），如果数据可能涉及到1970年之前，建议还是用UTC+8。
         * 另外，考虑到中国使用夏令时也只有80年代末那几年，简单地统一用UTC+8或许反而是更好的。
         * 直觉告诉我，这应该跟有关部门的规定有关系，Asia/Shanghai的时间归有关部门管辖，但是GMT+8是基于地理位置的时区，不受有关部门管辖
         */
        // 时区 Asia/Shanghai  存在夏令时   进入夏令时 时钟快一个小时，离开夏令时 时钟慢一个小时
        // GMT 标准时，不存在夏令时
        SimpleDateFormat simpleDateFormat00 = new SimpleDateFormat("yyyy-MM-dd");
        simpleDateFormat00.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        System.out.println(simpleDateFormat00.parse("1989-06-18")); // Sat Jun 17 23:00:00 GMT+08:00 1989  Sun Jun 18 00:00:00 CDT 1989

        // 建议设置为GMT+8 如果系统时区不一致，是Asia/Shanghai，那时间会+1h，还是当天，肯定比昨天要好
        // simpleDateFormat00.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
        simpleDateFormat00.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        System.out.println(simpleDateFormat00.parse("1989-06-18")); // Sun Jun 18 00:00:00 GMT+08:00 1989  Sun Jun 18 01:00:00 CDT 1989

        System.out.println(simpleDateFormat2.format(new Date())); // 11-十二月-2023 星期一  十二月 12月 星期一  简体中文，月份和星期的全称和简称是一样的
        System.out.println(simpleDateFormat3.format(new Date())); // 11-December-2023 Monday Dec 12月 Mon  英语

    }

}
